<template>
    <div class="analysis">
        <span v-if="btn.analysis" class="btn analysis-btn" @click="showAnalysis">解析</span>
        <span v-if="btn.position" class="btn position-btn" @click="handlePosition">原文定位</span>
    </div>
    <van-popup
        v-model:show="show"
        position="bottom"
        round
        overlay-class="overlay"
    >
        <div class="content">
            <div class="header">
                <span class="title">题目解析</span>
                <img src="@/assets/ic_close@2x.png" alt="" class="close-icon" @click="close">
            </div>
            <template v-if="!loading">
                <div class="list" v-if="formatAnalysis.length">
                    <div v-for="(item, index) in formatAnalysis" :key="index" class="analysis-item">
                        <p class="title">{{item.title}}</p>
                        <!-- 阅读 -->
                        <template v-if="topicType == 2">
                            <div class="html-text" v-html="item.content"></div>
                        </template>
                        <!-- 听力 -->
                        <template v-if="topicType == 1">
                            <template v-if="item.title == '原文'">
                                <div v-if="showListenAudio" class="player-warp">
                                    <div
                                        class="play-btn"
                                        :class="{ 'pause-btn': playing }"
                                        @click="handlePlay">
                                    </div>
                                    <div class="player-blank">
                                        <div class="time">{{ timeFormat(currentTime) }}</div>
                                        <div class="process">
                                            <van-slider
                                                v-model="progress"
                                                bar-height="4px"
                                                active-color="#FD453D"
                                                inactive-color="#D4D4D8"
                                                @change="onChange">
                                                <template #button>
                                                    <div class="custom-button"></div>
                                                </template>
                                            </van-slider>
                                        </div>
                                        <div class="totalTime">
                                            {{ timeFormat(duration) }}
                                        </div>
                                    </div>
                                </div>
                                <div class="good-topic">
                                    <div class="content-warp" v-show="viewTopicFlag">
                                        <div class="text">{{item.content}}</div>
                                    </div>
                                    <div class="show-or-hide" @click="viewTopicFlag = ! viewTopicFlag">
                                        <span v-show="viewTopicFlag">收起原文</span>
                                        <span v-show="!viewTopicFlag">显示原文</span>
                                    </div>
                                </div>
                            </template>
                            <template v-else>
                                <div class="html-text" v-html="item.content"></div>
                            </template>
                        </template>
                    </div>
                </div>
                <template v-else>
                    <div class="no-data">暂无解析</div>
                </template>
            </template>
            <van-loading class="loading" v-else size="24px" vertical>加载中...</van-loading>
        </div>
    </van-popup>
    <audio
        v-if="audioUrl && props.topicType == 1"
        ref="audioRef"
        id="audioPlayer"
        class="dialog-audioPlayer"
        style="display: none"
        controls
        preload="auto"
        :autoplay="false"
        :src="audioUrl"
    ></audio>
</template>

<script setup>
import { ref, computed, nextTick, watch } from 'vue'
import { apiGetTopicAnalysis, apiGetListenTopicAnalysis } from '@/api/exam'

const emit = defineEmits(['to-position', 'popup-show'])

const props = defineProps({
    topicId: {
        type: [String, Number],
        default: ''
    },
    partId: {
        type: [String, Number],
        default: ''
    },
    btn: {
        type: Object,
        default: () => ({
            position: true,
            analysis: true
        })
    },
    topicType: { // 1 听力 2 阅读
        type: [Number, String],
        default: 0
    },
    examId: {
        type: [Number, String],
        default: 0
    }
})

const show = ref(false)

const analysis = ref({}) // 解析

const loading = ref(false)

const audioUrl = ref('')

const playing = ref(false) // 播放状态

const duration = ref(0) // 音频时长

const currentTime = ref(0) // 当前播放时间

const audioRef = ref(null)

const progress = ref(0) // 播放进度

const viewTopicFlag = ref(false)

// 处理解析信息
const formatAnalysis = computed(() => {
    const fieldMap = {
        analysis: '解析',
        location: '定位词',
        highlightedText: '原文', // 阅读
        passage: '原文', // 听力
        translate: '翻译'
    }
    const covert = Object.entries(analysis.value)
    const list = []
    for (const key in fieldMap) {
        const value = fieldMap[key]
        covert.forEach(item => {
            const [k, v] = item
            if (k === key && v) {
                list.push({
                    title: value,
                    content: v,
                    field: k
                })
            }
        })
    }
    return list
})

// 有起止时间才展示听力播放器
const showListenAudio = computed(() => {
    const { beginTime, endTime } = analysis.value
    return (beginTime || beginTime == 0) && (endTime || endTime == 0)
})

watch(show, (val) => {
    if (!val) {
        audioRef.value && audioRef.value.pause()
    }
})

watch(audioRef, async(val) => {
    await nextTick()
    if (val) {
        bindEvent()
    }
})

async function bindEvent() {
    await nextTick()
    audioRef.value.load()
    audioRef.value.addEventListener('canplay', handleCanPlay)

    audioRef.value.addEventListener('timeupdate', handleTimeUpDate)

    audioRef.value.addEventListener('loadedmetadata', loadedmetadata)

    audioRef.value.addEventListener('play', () => {
        playing.value = true
    })

    audioRef.value.addEventListener('pause', () => {
        playing.value = false
    })
}

// 滑块拖动
function onChange(value) {
    audioRef.value.currentTime = (value / 100) * audioRef.value.duration
}

// 音频播放暂停
function handlePlay() {
    if (playing.value) {
        audioRef.value.pause()
    } else {
        audioRef.value.play()
    }
}

function handleCanPlay() {
    duration.value = audioRef.value && audioRef.value.duration || 0
}

function loadedmetadata() {
    audioRef.value && (audioRef.value.currentTime = analysis.value.beginTime / 1000)
}

function handleTimeUpDate() {
    if (audioRef.value) {
        currentTime.value = audioRef.value.currentTime || 0
        progress.value = (audioRef.value.currentTime / audioRef.value.duration) * 100
        if (audioRef.value.currentTime > (analysis.value?.endTime / 1000)) {
            audioRef.value.currentTime = analysis.value.beginTime / 1000
            audioRef.value.pause()
        }
    }
}

// 时间格式
function timeFormat(time) {
    let s = Math.floor(time % 60)
    let m = Math.floor(time / 60)
    if (s < 10) s = '0' + s
    if (m < 10) m = '0' + m
    return m + ':' + s
}

// 显示解析弹窗
async function showAnalysis() {
    if (!analysis.value?.topicId) {
        await getAnalysis()
    }
    await nextTick()
    show.value = true
    emit('popup-show', show.value)
}

// 获取解析内容
function getAnalysis() {
    if (props.topicId === analysis.value?.topicId) return
    loading.value = true
    const { partId, topicId, examId, topicType } = props
    const apiMap = {
        1: { // 听力
            api: apiGetListenTopicAnalysis,
            params: { examId, topicId }
        },
        2: { // 阅读
            api: apiGetTopicAnalysis,
            params: { partId, topicId }
        }
    }
    return apiMap[topicType]['api']({ ...apiMap[topicType]['params'] }).then(async res => {
        analysis.value = res
        audioUrl.value = res?.audioUrl || ''
        await nextTick()
        loading.value = false
    }).catch((err) => {
        console.log(err, 'err')
    })
}

// 点击原文定位
async function handlePosition() {
    if (!analysis.value?.topicId) {
        await getAnalysis()
    }
    await nextTick()
    emit('to-position', analysis.value)
}

// 解析高亮html在高亮标签外包一层div设置背景色
function formatHtml(html) {
    if (!html) return ''
    const parser = new DOMParser()
    const doc = parser.parseFromString(html, 'text/html')

    const elements = doc.body.querySelectorAll('*')
    elements.forEach(element => {
        const backgroundColor = element.style.backgroundColor
        if (backgroundColor) {
            const wrapperSpan = document.createElement('div')
            wrapperSpan.className += 'wrap-highlight'
            element.parentNode.replaceChild(wrapperSpan, element)
            wrapperSpan.appendChild(element)
        }
    })

    const wrappedHtml = doc.body.innerHTML
    return wrappedHtml
}

function close() {
    show.value = false
}

</script>

<style lang="scss" rel="stylesheet/scss" scoped>
// rem基准值：1rem = 30px
.analysis{
    display: inline-flex;
    align-items: center;
    line-height: normal;
}
.btn{
    color: #fff;
    border-radius: .13rem;
    font-size: .8rem;
    padding: .33rem .67rem;
    box-sizing: border-box;
    margin: 0 .33rem;
}
.analysis-btn{
    background-color: #B2A0FA;
}
.position-btn{
    background-color: #FFC869;
}
.overlay{
    background: rgba(0,0,0,.7);
}
.content{
    position: relative;
    padding: 1.3rem 1rem 3.33rem;
    box-sizing: border-box;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 26.67rem;
    min-height: 16.67rem;

    .header{
        display: flex;
        align-items: center;
        justify-content: center;
        .title{
            color: #333;
            font-size: 1.07rem;
            font-weight: bold;
        }
        .close-icon{
            position: absolute;
            right: 1.07rem;
            // top: 1.4rem;
            width: .87rem;
            height: .87rem;
        }
    }
    .list{
        flex: 1;
        overflow: auto;
    }
    .analysis-item{
        margin-bottom: .97rem;
        .title{
            color: #333;
            font-size: .93rem;
            margin-bottom: .67rem;
            font-weight: bold;
        }
        .html-text{
            width: 100%;
            background-color: #F6F8FC;
            border-radius: .33rem;
            color: #333;
            font-size: .93rem;
            padding: .97rem .67rem;
            box-sizing: border-box;
        }
        .player-warp{
            display: flex;
            align-items: center;
            background-color: #F7F7F7;
            border-radius: .33rem;
            padding: .67rem .57rem;
            box-sizing: border-box;
            margin-right: 4.13rem;
            .player-blank {
                display: flex;
                align-items: center;
                justify-content: space-evenly;
                flex: 1;
                .time {
                    width: 2.8rem;
                    text-align: left;
                    color: #999999;
                    font-size: 0.75rem;
                }
                .process {
                    flex: 1;
                }
                .totalTime {
                    font-size: 0.75rem;
                    color: #999999;
                    width: 2.8rem;
                    text-align: right;
                }
            }
            .play-btn {
                width: 1.8rem;
                height: 1.8rem;
                margin-right: .67rem;
                background-image: url('@/assets/ic_play.png');
                background-size: 100%;
                background-repeat: no-repeat;
                cursor: pointer;
            }
            .pause-btn {
                background-image: url('@/assets/ic_pause.png');
            }
            .custom-button {
                width: .8rem;
                height: .8rem;
                background: #fd453d;
                box-shadow: 0 2px 4px 0 rgba(253, 69, 61, 0.67);
                border-radius: 50%;
            }
        }
        .good-topic{
            width: 100%;
            font-size: .93rem;
            color: #333;
            margin-top: 1rem;
            background-color: #F6F8FC;
            border-radius: .33rem;
            .content-warp{
                padding: .97rem .63rem 0;
                box-sizing: border-box;
                .text{
                    line-height: 1.33rem;
                    box-sizing: border-box;
                    border-bottom: 1px dashed #DEDEDE;
                    padding-bottom: 1rem;
                }
            }
            .show-or-hide{
                font-size: .8rem;
                width: 100%;
                color: #2E55E5;
                text-align: center;
                height: 2.6rem;
                line-height: 2.6rem;

            }
        }
    }
    .no-data{
        text-align: center;
        font-size: .8rem;
        color: #999;
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .loading{
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
    }
}
</style>
